package com.witframework.remote;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.witframework.util.CryptoUtility;




/**
 * 远程调用的服务器处理类,要是有remote包，需要在提供远程服务的应用上配置
 * WitRemoteServlet，如下：
 * <code><pre>
 * 	&lt;servlet&gt;
 *		&lt;servlet-name&gt;WitRemoteServlet&lt;/servlet-name&gt;
 *		&lt;servlet-class&gt;com.witframework.remote.WitRemoteServlet&lt;/servlet-class&gt;
 *	&lt;/servlet&gt;
 *	&lt;servlet-mapping&gt;
 *		&lt;servlet-name&gt;WitRemoteServlet&lt;/servlet-name&gt;
 *		&lt;url-pattern&gt;/httpinvoker&lt;/url-pattern&gt;
 *	&lt;/servlet-mapping&gt;
 * </pre></code>
 *
 * @author wuxinyang
 */
public class WitRemoteServlet extends GenericServlet {
	static Logger logger = Logger.getLogger	( WitRemoteServlet.class) ;
	@Override
	public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
		RemoteRequest request = null;
		String password=req.getParameter("password");
		if(password==null||!new String(CryptoUtility.encrypt(password)).equals("vcdzoBIS/1qXcossle5AxaopH3O85lqW")){
			
			ObjectInputStream in = new ObjectInputStream(req.getInputStream());
			resp.setContentType("application/octest-stream");
			try {
				request = (RemoteRequest)in.readObject();
				logger.debug("invoke request:"+request.toString());
			} catch (ClassNotFoundException e) {
				outObject(resp,new RemoteException(e));
			}			
			outObject(resp,LocalRequestProcessor.processorLocalhost(request));
		}else{
			String obj=req.getParameter("object");
			String method=req.getParameter("method");
			String param=req.getParameter("param");
			request=new RemoteRequest("localhost:8080","class:"+obj+"/"+method);
			if(req.getParameter("type")!=null)
				request.setServiceType(req.getParameter("type"));		
			request.setResultAsXml(true);
			if(StringUtils.isNotEmpty(param))
				request.setArgument((Object[])StringUtils.split(param, ","));
			resp.setContentType("text/xml;charset=UTF-8");
			resp.getWriter().write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+(String)LocalRequestProcessor.processorLocalhost(request));
		}		
		
	}

	private void outObject(ServletResponse resp,Object o) {
		ByteArrayOutputStream byteout = new ByteArrayOutputStream();
		ObjectOutputStream out=null;
		ServletOutputStream servletout=null;
		try {
			out = new ObjectOutputStream(byteout);
			out.writeObject(o);
			byte buf[] = byteout.toByteArray();
			resp.setContentLength(buf.length);
			servletout = resp.getOutputStream();
			servletout.write(buf);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			close(servletout);
			close(out);
		}
	}
	private static void close(Closeable object){
		try {
			object.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
